<template>
  <div>
    <Category :disable="!isAttrList" />
    <el-card
      shadow="always"
      :body-style="{ padding: '20px' }"
      v-if="isAttrList"
      style="margin: 20px 0px"
    >
      <template #header>
        <el-button
          type="primary"
          icon="ele-Plus"
          @click="addAttr"
          :disabled="!category3Id"
          >添加属性</el-button
        >
      </template>
      <!-- card body -->
      <el-table :data="attrList" border stripe>
        <el-table-column
          type="index"
          width="120"
          align="center"
          label="序号"
        ></el-table-column>
        <el-table-column
          width="180"
          label="属性名称"
          prop="attrName"
        ></el-table-column>
        <el-table-column label="属性值名称列表">
          <template v-slot="{ row }">
            <el-tag
              type="success"
              v-for="item in row.attrValueList"
              :key="item.id"
              :style="{ marginLeft: '10px' }"
              >{{ item.valueName }}</el-tag
            >
          </template>
        </el-table-column>
        <el-table-column width="300" label="操作">
          <template v-slot="{ row }">
            <el-button
              type="warning"
              size="default"
              icon="ele-Edit"
              @click="updateAttr(row)"
            ></el-button>
            <el-popconfirm
              title="是否确认删除该属性?"
              @confirm="deleteAttr(row.id)"
            >
              <template #reference>
                <el-button type="danger" icon="ele-Delete"></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <el-card
      shadow="always"
      :body-style="{ padding: '20px' }"
      :style="{ marginTop: '25px' }"
      v-else
    >
      <el-form :inline="true">
        <el-form-item label-width="auto" label="属性名">
          <el-input
            placeholder="请输入属性名"
            v-model="newAttrValueList.attrName"
          ></el-input>
        </el-form-item>
      </el-form>
      <div>
        <el-button
          type="primary"
          size="default"
          @click="addAttrValue"
          :disabled="!newAttrValueList.attrName"
          >添加属性值</el-button
        >
        <el-button size="default" @click="isAttrList = true">取消</el-button>
      </div>
      <el-table
        :data="newAttrValueList.attrValueList"
        border
        stripe
        :style="{ margin: '25px 0' }"
      >
        <el-table-column type="index" width="100" label="序号" />
        <el-table-column label="属性值名称">
          <template v-slot="{ row, $index }">
            <el-input
              v-model="row.valueName"
              v-if="row.isEdit"
              placeholder="请输入属性值名称"
              @blur="toLook(row, $index)"
              @keyup.enter="toLook(row, $index)"
              ref="editIpt"
            ></el-input>
            <div @click="toEdit(row)" v-else>{{ row.valueName }}</div>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{ row, $index }">
            <el-popconfirm
              :title="`是否确认删除${row.valueName}`"
              @confirm="deleteAttrValue($index)"
            >
              <template #reference>
                <el-button type="danger" size="small" icon="ele-Delete"
                  >删除</el-button
                >
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <div>
        <el-button
          type="primary"
          size="default"
          @click="save"
          :disabled="
            newAttrValueList.attrValueList.length === 0 ||
            newAttrValueList.attrName === ''
          "
          >保存</el-button
        >
        <el-button size="default" @click="isAttrList = true">取消</el-button>
      </div>
    </el-card>
  </div>
</template>

<script lang="ts">
  import { defineComponent } from "vue"

  export default defineComponent({
    name: "Attr",
  })
</script>

<script setup lang="ts">
  import { reqAttrList, reqAddOrUpdateAttr, reqDeleteAttr } from "@/api/attr"
  import { ref, watch, nextTick } from "vue"
  import useCategoryStore from "@/stores/category"
  import { storeToRefs } from "pinia"
  import type {
    attrListType,
    attrItemType,
    attrValueItemType,
  } from "@/api/attr"
  import { cloneDeep } from "lodash"
  import { ElMessage } from "element-plus"

  //得到category的pinia中的store对象
  const categoryStore = useCategoryStore()

  //从pinia中拿到category的3个id,用来请求列表
  const { category1Id, category2Id, category3Id } = storeToRefs(categoryStore)

  //设置一个保存平台属性的数据
  const attrList = ref<attrListType>([])

  //封装一个请求平台属性列表的函数
  const getAttrList = async () => {
    //发送请求
    const res = await reqAttrList(
      category1Id.value as number,
      category2Id.value as number,
      category3Id.value as number
    )

    //把得到的结果赋值给数据保存
    attrList.value = res
  }

  //监听category3Id,改变以后才能发送请求
  watch(category3Id, (newVal) => {
    //如果category3Id变成null的时候,是不会发送请求的,并且要清空当前的属性列表
    if (!newVal) {
      attrList.value = []
      return
    }
    //不能直接调用发送请求的函数。需要在选择条件都选好之后再发送请求
    getAttrList()
  })

  //定义一个响应式数据,代表当前展示的是列表还是新增的结构
  const isAttrList = ref(true)

  //定义一个数据获得页面中存在的那个input的元素
  const editIpt = ref()

  //定义一个修改或者新增的 请求体对象, 用来收集好数据之后,进行发送请求
  const newAttrValueList = ref<attrItemType>({
    attrName: "",
    categoryId: category3Id.value as number,
    categoryLevel: 3,
    attrValueList: [],
  })

  //添加属性按钮的事件回调函数
  const addAttr = () => {
    //先切换至新增或修改的页面
    isAttrList.value = false
    //再清空之前的旧数据残留
    newAttrValueList.value = {
      attrName: "",
      categoryId: category3Id.value as number,
      categoryLevel: 3,
      attrValueList: [],
    }
  }

  //添加属性值按钮的事件回调函数
  const addAttrValue = () => {
    //先向属性值列表中添加一个数据，让table生成一条数据，可以新增属性值
    newAttrValueList.value.attrValueList.push({
      valueName: "",
      isEdit: true, //是否是编辑模式
    })

    //让table中的input自动获取焦点
    //数据虽然改变了,但是视图还是没有更新好,所以要使用nextTick方法(等下一次的DOM更新完成以后执行回调函数)
    nextTick(() => {
      editIpt.value.focus()
    })
  }

  //当新增属性值的input失去焦点(编辑模式--查看模式)的事件回调函数
  const toLook = (row: attrValueItemType, index: number) => {
    row.isEdit = false

    //判断输入的内容是否为空,如果为空,则删除当前新的属性值数据
    if (!row.valueName) {
      newAttrValueList.value.attrValueList.splice(index, 1)
      ElMessage.warning("属性值不能为空！")
    }

    //判断输入的内容是否重复,如果重复也要删除
    const isReapt = newAttrValueList.value.attrValueList.some((item) => {
      //先排除自己和自己比较
      if (item === row) return
      //如果其他人和自己比较有相等的 则直接返回true
      return item.valueName === row.valueName
    })
    //如果有重复的,则删除当前数据
    if (isReapt) {
      newAttrValueList.value.attrValueList.splice(index, 1)
      ElMessage.warning("属性值不能重复！")
    }
  }

  //当点击属性值的时候 切换到input（查看模式--编辑模式）的事件回调函数
  const toEdit = (row: attrValueItemType) => {
    row.isEdit = true
    //切换到编辑模式的时候,需要让input主动的获取焦点
    nextTick(() => {
      editIpt.value.focus()
    })
  }

  //删除某个属性值的事件回调函数
  const deleteAttrValue = (index: number) => {
    newAttrValueList.value.attrValueList.splice(index, 1)
    ElMessage.success("删除成功！")
  }

  //点击修改平台属性按钮的事件回调函数
  const updateAttr = (row: attrItemType) => {
    //回填数据（需要深拷贝）
    newAttrValueList.value = cloneDeep(row)

    //一旦点击修改数据按钮，则给每一条数据身上增加一个可编辑的属性--isEdit,默认是false
    newAttrValueList.value.attrValueList.forEach(
      (item) => (item.isEdit = false)
    )
    //切换至新增或修改的视图
    isAttrList.value = false
  }

  //修改或者新增的保存按钮的事件回调函数
  const save = async () => {
    //发起请求（参数就是整个newAttrValueList）
    await reqAddOrUpdateAttr(newAttrValueList.value)
    //保存完成后切换到列表展示
    isAttrList.value = true
    //保存并跳转后需重新加载最新数据
    getAttrList()
  }

  //删除某个平台属性的事件回调函数
  const deleteAttr = async (id: number) => {
    //发送删除请求
    await reqDeleteAttr(id)
    ElMessage.success("删除成功！")
    //删除完成后获取最新数据从而改变视图
    getAttrList()
  }
</script>

<style scoped lang="scss"></style>
